﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using EmitMapper;
using InnovaApp.Layers.CommonLayer;
using InnovaApp.Layers.DataLayer;
using InnovaApp.Layers.DomainLayer;
using InnovaApp.Layers.ResourcesLayer.Properties;
using InnovaApp.Portals.MVC4Portal.Models;
using InnovaApp.Portals.MVC4Portal.Models.JSonModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels.ContactManagement;
using InnovaApp.Portals.MVC4Portal.Models.MetaModels.OrderManagement;
using INNOVACALL.Framework.Common;
using INNOVACALL.Framework.Common.CodeFormatting;
using INNOVACALL.Framework.Common.Models;
using INNOVACALL.Framework.Common.MVCHelpers;

namespace InnovaApp.Portals.MVC4Portal.Controllers
{
	/// <summary>
	/// Controller inherits _Controllers_Base<T> to avoid use of untyped ViewBag
	/// Copy Home controller and Replace Home by AdvancedSamples_OrderWithDetails
	/// </summary>
	public class AdvancedSamples_OrderWithDetailsController : _Controllers_Base<AdvancedSamples_OrderWithDetailsModel>
	{
		protected override void Initialize(System.Web.Routing.RequestContext requestContext)
		{
			base.eMethodBase = "InnovaApp.Portals.InnovaAppFrontOfficePortal.Controllers.AdvancedSamples_OrderWithDetailsController";
			base.specificCssCollection = new string[] { "_FormCommon.css", "Views/AdvancedSamples_OrderWithDetails.css", "ClientComponents/CodeFormatting/csharp.css", "ClientComponents/KendoUI/kendo.common.min.css", "ClientComponents/KendoUI/kendo.blueopal.min.css" };
			base.specificJSCollection = null;
			base.dynamicJSCollection = new string[] { "/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.js" };
			base.specificJqueryJSCollection = new string[] { "ClientComponents/KendoUI/kendo.web.min.js", "InnovacallJS/views.js", "InnovacallJS/AdvancedSamples_OrderWithDetails/AdvancedSamples_OrderWithDetails.js" };
            base.jsVariables = null;
			base.externalCSS = null;
			base.Meta.Add(enMeta.Description, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Description);
			base.Meta.Add(enMeta.Keywords, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Keywords);
			base.Meta.Add(enMeta.Subject, Resources.View_AdvancedSamples_OrderWithDetails_Meta_Subject);

			base.Initialize(requestContext);
		}

		/// <summary>
		/// Initial response
		/// </summary>
		/// <returns></returns>
		[HttpGet, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
		public ActionResult Index()
		{
			//NEVER USES VIEW BAG AGAIN !
			//ViewBag.Message = "Modify this template to kick-start your ASP.NET MVC application.";
			using (DataRepositories _dataContext = new DataRepositories())
			{
				base.InitView(
					Resources.View_AdvancedSamples_OrderWithDetails_PageTitle,
					string.Empty,
					specificCssCollection,
					specificJSCollection,
					dynamicJSCollection,
					specificJqueryJSCollection,
                    jsVariables,
					externalCSS,
					Meta,
					_dataContext,
					true);
				try
				{
					PrepareEmptyOrder(_dataContext);
				}
				catch (INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException iDIe)
				{
                    string returnURL = Server.UrlEncode(Request.Url.AbsoluteUri);
                    string ScriptToExecute = string.Format("$.fn.jqDialogAlert('{0}','{1}','{2}{3}');",
                        Resources.View_AdvancedSamples_ErrMsgContactAccountNotCreated_Title,
                        Resources.View_AdvancedSamples_ErrMsgContactAccountNotCreated_Message,
                        "/Sample_BasicForm_MyProfile?ReturnUrl=",
                        returnURL);
                    base.jsVariables = new string[] { "var scriptToExecute='" + ScriptToExecute.Replace("\'", "\\\'") + "'" };
                    ContentData.CurrentOrder = new Order_MetaModel();
                    ContentData._JSVariables = base.jsVariables.ToList();
				}

				#region Involved code rendering
				INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel InvolvedSourceCode;
				INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel InvolvedSubSourceCode;
				ContentData.InvolvedCode = new InvolvedCodeModel();
				InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();

				#region Views, partials & template editors

				InvolvedSourceCode.TabStripName = "Views, partials & template editors";
				InvolvedSourceCode.TabStripContent = string.Empty;
				InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/AdvancedSamples_OrderWithDetails/Index.cshtml" };
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Layout", TabStripContent = "/Views/Shared/_Layout.cshtml" };
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSubSourceCode.TabStripName = "Partials";
				InvolvedSubSourceCode.TabStripContent = string.Empty;
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "_AdvancedSamples_OrderWithDetails_DetailRefresh.cshtml", TabStripContent = "/Views/Shared/_AdvancedSamples_OrderWithDetails_DetailRefresh.cshtml" });
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSubSourceCode.TabStripName = "Editor templates";
				InvolvedSubSourceCode.TabStripContent = string.Empty;
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Order_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/Order_MetaModel.cshtml" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "OrderDetail_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/OrderDetail_MetaModel.cshtml" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "OrderTotal_MetaModel.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/OrderTotal_MetaModel.cshtml" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "Order_MetaModel_Refresh.cshtml", TabStripContent = "/Views/Shared/EditorTemplates/Order_MetaModel_Refresh.cshtml" });
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				ContentData.InvolvedCode.Add(InvolvedSourceCode);
				#endregion

				#region Controller
				ContentData.InvolvedCode.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/AdvancedSamples_OrderWithDetailsController.cs" });
				#endregion

				#region Models
				InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSourceCode.TabStripName = "Models";
				InvolvedSourceCode.TabStripContent = string.Empty;
				InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "AdvancedSamples_OrderWithDetailsModel", TabStripContent = "/Models/AdvancedSamples_OrderWithDetailsModel.cs" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Order_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/Order_MetaModel.cs" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "OrderDetail_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/OrderDetail_MetaModel.cs" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "OrderTotal_MetaModel", TabStripContent = "/Models/MetaModels/OrderManagement/OrderTotal_MetaModel.cs" });
				ContentData.InvolvedCode.Add(InvolvedSourceCode);
				ContentData.InvolvedCode.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "JSon Model", TabStripContent = "/Models/JSonModels/OrderDetail_JSonModel.cs" });
				#endregion

				#region Javascripts
				InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSourceCode.TabStripName = "Javascripts";
				InvolvedSourceCode.TabStripContent = string.Empty;
				InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Javascript, TabStripName = "View JS", TabStripContent = "/Scripts/InnovacallJS/AdvancedSamples_OrderWithDetails/AdvancedSamples_OrderWithDetails.js" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Javascript, TabStripName = "Layout JS", TabStripContent = "/Scripts/InnovacallJS/_Layout/_Layout.js" });
				ContentData.InvolvedCode.Add(InvolvedSourceCode);
				#endregion

				#region CSS
				InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSourceCode.TabStripName = "CSS";
				InvolvedSourceCode.TabStripContent = string.Empty;
				InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "View CSS", TabStripContent = "/Content/Views/AdvancedSamples_OrderWithDetails.css" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "Form Common CSS", TabStripContent = "/Content/_FormCommon.css" });
				InvolvedSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Css, TabStripName = "Site (Layout) CSS", TabStripContent = "/Content/_Site.css" });
				ContentData.InvolvedCode.Add(InvolvedSourceCode);
				#endregion

				#region Generated client files
				InvolvedSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSourceCode.TabStripName = "Generated client files";
				InvolvedSourceCode.TabStripContent = string.Empty;
				InvolvedSourceCode.Language = enCodeLanguage._MultipleCodes;

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSubSourceCode.TabStripName = "Javascript";
				InvolvedSubSourceCode.TabStripContent = string.Empty;
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/ScriptsGController.cs" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.cshtml" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.GeneratedJavascript, TabStripName = "Generated javascript", TabStripContent = "/ScriptsG/inoAdvancedSamples_OrderWithDetailsDynamic.js" });
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				InvolvedSubSourceCode = new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel();
				InvolvedSubSourceCode.TabStripName = "CSS";
				InvolvedSubSourceCode.TabStripContent = string.Empty;
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.cSharp, TabStripName = "Controller", TabStripContent = "/Controllers/CSSGController.cs" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.Html, TabStripName = "View", TabStripContent = "/Views/CSSG/site.cshtml" });
				InvolvedSubSourceCode.SubCodes.Add(new INNOVACALL.Framework.Common.Models.MetaModels.CodeFile_MetaModel() { Language = enCodeLanguage.GeneratedCss, TabStripName = "Generated CSS (from _site.css)", TabStripContent = "/CSSG/Site.css" });
				InvolvedSourceCode.SubCodes.Add(InvolvedSubSourceCode);

				ContentData.InvolvedCode.Add(InvolvedSourceCode);
				#endregion


				RenderCodeFiles(ContentData.InvolvedCode);

				#endregion
			}
			return View(ContentData);
		}

		/// <summary>
		/// Add detail row in model (no database persistance yet)
		/// </summary>
		/// <param name="model"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
		public JsonResult AddRow(AdvancedSamples_OrderWithDetailsModel model)
		{
			string eMethod = eMethodBase + "AddRow[POST]";
			object eParameters = new { model = "model" };
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			int newId = -1;
			if (model.CurrentOrder.Details.Count > 0)
			{
				///New rows have negative id, this query find the smaller and remove 1
				newId = model.CurrentOrder.Details.Where(x => x.Id < 0).OrderByDescending(x => x.Id).First().Id - 1;
			}
			model.CurrentOrder.NewRow.Id = newId;
			model.CurrentOrder.NewRow.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Remove;
			model.CurrentOrder.Details.Add(model.CurrentOrder.NewRow);
			string htmlContent = PrepareContent(model);
			//string htmlContent = base.RenderPartialViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
			toReturn.Data = new { @success = true, @divToUpdate = "#divOrderDetailContainer", @htmlContent = htmlContent, @scriptToExecute = "$.fn.ReloadLists();" };
			return toReturn;
		}

		private string PrepareContent(AdvancedSamples_OrderWithDetailsModel model)
		{
			string toReturn = string.Empty;
			model.CurrentOrder.NewRow = EmptyNewRow(model.CurrentOrder.Id);
			//There is no persistance for row mode
			model.CurrentOrder.Totals = new OrderTotal_MetaModel();
			int rowId = -1;
			foreach (var d in model.CurrentOrder.Details)
			{
				d.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Remove;
				
				d.Id= rowId;

				model.CurrentOrder.Totals.ExcludingTaxesTotal += d.TotalPrice;
				model.CurrentOrder.Totals.TaxesTotal += d.VatTotal;
				model.CurrentOrder.Totals.IncludedTaxesTotal += d.AllTaxeIncludedTotal;
				
				rowId--;
			}
			toReturn = this.RenderViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
			return toReturn;
		}

		/// <summary>
		/// Remove an existing Row in model, the row is tagged "isRemoved=true"
		/// </summary>
		/// <param name="Id"></param>
		/// <param name="model"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
		public JsonResult RemoveRow(int Id, AdvancedSamples_OrderWithDetailsModel model)
		{
			string eMethod = eMethodBase + "RemoveRow[POST]";
			object eParameters = new { model = "model" };
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			model.CurrentOrder.Details.Remove(model.CurrentOrder.Details.Where(x => x.Id == Id).First());
			int i = -1;
			model.CurrentOrder.Details.Where(x => x.Id < 0).ToList().ForEach(x => x.Id = i--);
			string htmlContent = PrepareContent(model);
			toReturn.Data = new { @success = true, @divToUpdate = "#divOrderDetailContainer", @htmlContent = htmlContent, @scriptToExecute = "$.fn.ReloadLists();" };
			return toReturn;
		}

		/// <summary>
		/// Final post, the order is saved in the database
		/// </summary>
		/// <param name="model"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
		public JsonResult Index(AdvancedSamples_OrderWithDetailsModel model)
		{
			string eMethod = eMethodBase + "Index[POST]";
			object eParameters = new { model = "model" };
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			//if model.Id = -1, new order
			Order orderToAddUpdate;
			using (TransactionScope _ts = new TransactionScope())
			{
				using (DataRepositories _dataContext = new DataRepositories())
				{
					//Persist to database
				}
				_ts.Complete();
			}
			return toReturn;
		}

		/// <summary>
		/// GetItemDescription
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
		public JsonResult GetDeliveryModeDescriptionDescription(int Id)
		{
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			string htmlResult;
			using (DataRepositories _dataContext = new DataRepositories())
			{
				htmlResult = Server.HtmlEncode(StringEnum.GetStringValue(EnumTools.EnumTypeTo<enDeliveryModes>(Id)));
				toReturn.Data = new { @success = true, @divToUpdate = "#divDeliveryModeDescription", @htmlResult = htmlResult };
			}
			return toReturn;
		}

		/// <summary>
		/// UpdateRow
		/// </summary>
		/// <param name="IdproductId"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
		public JsonResult UpdateDetailRowAndTotals(
			int id,
			string orderRef,
			int rowId,
			int productId,
			int qty,
			decimal currentRow_TotalPrice,
			decimal currentRow_VatTotal,
			decimal currentRow_AllTaxeIncludedTotal,
			decimal totals_ExcludingTaxesTotal,
			decimal totals_TaxesTotal,
			decimal totals_IncludedTaxesTotal
		)
		{
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			OrderDetail_JSonModel toReturnData;
			using (DataRepositories _dataContext = new DataRepositories())
			{
				toReturnData = PrepareRow(_dataContext, id, orderRef, rowId, productId, qty, currentRow_TotalPrice, currentRow_VatTotal, currentRow_AllTaxeIncludedTotal, totals_ExcludingTaxesTotal, totals_TaxesTotal, totals_IncludedTaxesTotal);
			}
			toReturn.Data = toReturnData.Data;
			return toReturn;
		}

		/// <summary>
		/// UpdateRow
		/// </summary>
		/// <param name="IdproductId"></param>
		/// <returns></returns>
		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
		public JsonResult UpdateRow(int productId, int qty)
		{
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			string htmlResult;
			if (productId > 0)
			{
				using (DataRepositories _dataContext = new DataRepositories())
				{
					Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == productId).FirstOrDefault();
					if (dbProduct != null)
					{
						double vat = dbProduct.VAT.Value;
						double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * qty;
						double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
						double vatTotal = allTaxeIncludedTotal - totalPrice;
						toReturn.Data = new
						{
							@success = true,
							@productDescription = dbProduct.Description,
							@unitPrice = string.Format("{0:0.00}", dbProduct.UnitPrice),
							@totalPrice = string.Format("{0:0.00}", totalPrice),
							@appliedVATRate = string.Format("{0:0.00}", vat),
							@vatTotal = string.Format("{0:0.00}", vatTotal),
							@allTaxeIncludedTotal = string.Format("{0:0.00}", allTaxeIncludedTotal)
						};
					}
					else
					{
						toReturn.Data = new { @success = false, @message = Resources.View_Order_ErrMsg_ProductNotFound };
					}
				}
			}
			else
			{
				toReturn.Data = new
				{
					@success = true,
					@productDescription = string.Empty,
					@unitPrice = "0.00",
					@totalPrice = "0.00",
					@appliedVATRate = "0.00",
					@vatTotal = "0.00",
					@allTaxeIncludedTotal = "0.00"
				};
			}
			return toReturn;
		}

		[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache -- Authorize, Removed for search engine indexing
		public JsonResult GetAddress(int Id, string textAreaToUpdate)
		{
			JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			string htmlResult;
			using (DataRepositories _dataContext = new DataRepositories())
			{
				ContactAddress dbAddress = _dataContext.ContactAddress_Rep.Query(x => x.Id == Id).FirstOrDefault();
				htmlResult = Server.HtmlEncode(dbAddress.Address_1) + "<br/>";
				if (!string.IsNullOrEmpty(dbAddress.Address_2))
				{
					htmlResult += Server.HtmlEncode(dbAddress.Address_2) + "<br/>";
				}
				if (!string.IsNullOrEmpty(dbAddress.Address_3))
				{
					htmlResult += Server.HtmlEncode(dbAddress.Address_3) + "<br/>";
				}
				htmlResult += Server.HtmlEncode(dbAddress.ZipCode) + "&nbsp;" + Server.HtmlEncode(dbAddress.Town) + "<br/>";
				htmlResult += Server.HtmlEncode(dbAddress.Country);

				toReturn.Data = new { @success = true, @divToUpdate = textAreaToUpdate, @htmlResult = htmlResult };
			}
			return toReturn;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="_dataContext"></param>
		/// <param name="id">db Id of Current Order</param>
		/// <param name="orderRef">Text order reférence</param>
		/// <param name="rowId"></param>
		/// <param name="productId"></param>
		/// <param name="qty"></param>
		/// <returns></returns>
		private OrderDetail_JSonModel PrepareRow(
			DataRepositories _dataContext,
			int id,
			string orderRef,
			int rowId,
			int productId,
			int qty,
			decimal currentRow_TotalPrice,
			decimal currentRow_VatTotal,
			decimal currentRow_AllTaxeIncludedTotal,
			decimal totals_ExcludingTaxesTotal,
			decimal totals_TaxesTotal,
			decimal totals_IncludedTaxesTotal
		)
		{
			OrderDetail_JSonModel toReturn = new OrderDetail_JSonModel();
			Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == productId).FirstOrDefault();
			if (dbProduct != null)
			{
				double vat = dbProduct.VAT.Value;
				double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * qty;
				double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
				double vatTotal = allTaxeIncludedTotal - totalPrice;
				toReturn.appliedVATRate = dbProduct.VAT.Value;
				toReturn.unitPrice = double.Parse(dbProduct.UnitPrice.ToString());
				toReturn.message = string.Empty;
				toReturn.productDescription = dbProduct.Description;
				toReturn.success = true;
				toReturn.totalPrice = totalPrice;
				toReturn.unitPrice = double.Parse(dbProduct.UnitPrice.ToString());
				toReturn.vatTotal = vatTotal;
				toReturn.allTaxeIncludedTotal = allTaxeIncludedTotal;
				if (id == -99)
				{
					toReturn.updateTotals = false;
					toReturn.totals_ExcludingTaxesTotal = 0;
					toReturn.totals_TaxesTotal = 0;
					toReturn.totals_IncludedTaxesTotal = 0;
				}
				else
				{
					toReturn.updateTotals = true;
					toReturn.totals_ExcludingTaxesTotal = (double)totals_ExcludingTaxesTotal - (double)currentRow_TotalPrice + toReturn.totalPrice;
					toReturn.totals_TaxesTotal = (double)totals_TaxesTotal - (double)currentRow_VatTotal + toReturn.vatTotal;
					toReturn.totals_IncludedTaxesTotal = (double)totals_IncludedTaxesTotal - (double)currentRow_AllTaxeIncludedTotal + toReturn.allTaxeIncludedTotal;
				}
			}
			else
			{
				toReturn.appliedVATRate = 0;
				toReturn.unitPrice = 0;
				toReturn.message = string.Empty;
				toReturn.productDescription = string.Empty;
				toReturn.success = true;
				toReturn.totalPrice = 0;
				toReturn.unitPrice = 0;
				toReturn.vatTotal = 0;
				toReturn.allTaxeIncludedTotal = 0;
				toReturn.updateTotals = false;
				toReturn.totals_ExcludingTaxesTotal = 0;
				toReturn.totals_TaxesTotal = 0;
				toReturn.totals_IncludedTaxesTotal = 0;
			}

			return toReturn;
		}

		/// <summary>
		/// This private method feed MetaModel items
		/// </summary>
		/// <param name="_dataContext"></param>
		/// <returns></returns>
		private void PrepareEmptyOrder(DataRepositories _dataContext)
		{
			string eMethod = eMethodBase + ".PrepareEmptyOrder";
			object eParameters = new { @_dataContext = "[DataContext]" };

			IEnumerable<VAT> dbVATs = _dataContext.VAT_Rep.GetAll().AsEnumerable();

			ContentData.VATs = new List<SelectListItem>(
				dbVATs.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Description, Selected = false }).AsEnumerable()
			);
			ContentData.VATs.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

			IEnumerable<Product> dbProducts = _dataContext.Product_Rep.GetAll().OrderBy(x => x.Name).AsEnumerable();
			ContentData.Products = new List<SelectListItem>(
				dbProducts.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name, Selected = false }).AsEnumerable()
			);
			ContentData.Products.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

			Contact dbContact = _dataContext.InnoAppUser_Rep.GetById((Guid)Membership.GetUser().ProviderUserKey).Contact.FirstOrDefault();
			if (dbContact == null)
			{
				throw new INNOVACALL.Framework.Common.InnovacallExceptions.DataIntegrityException(eMethod, eParameters, Resources.View_AdvancedSamples_OrderWithDetails_CustomerMustBeSetBefore);
			}
			ContentData.CurrentOrder = new Models.MetaModels.Order_MetaModel();
			ContentData.CurrentOrder.OrderRef = "NEW";
			ContentData.CurrentOrder.Id = -1;
			ContentData.CurrentOrder.FK_Contact = dbContact.Id;
			ContentData.CurrentOrder.CurrentContact = ObjectMapperManager.DefaultInstance.GetMapper<Contact, ContactViewer_MetaModel>().Map(dbContact);
			ContentData.CurrentOrder.CurrentContact.Genre = StringEnum.GetStringValue(EnumTools.EnumTypeTo<enGenres>(ContentData.CurrentOrder.CurrentContact.FK_Genre));

			IEnumerable<DeliveryMode> dbDeliveryModes = _dataContext.DeliveryMode_Rep.GetAll().OrderBy(x => x.SortIndex).AsEnumerable();
			ContentData.CurrentOrder.DeliveryModes = new List<SelectListItem>(
				dbDeliveryModes.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name, Selected = false }).AsEnumerable()
			);
			ContentData.CurrentOrder.DeliveryModes.Insert(0, new SelectListItem() { Value = "-1", Text = " ", Selected = true });

			ContentData.CurrentOrder.OrderDate = DateTime.Now;
			ContentData.CurrentOrder.FK_Contact = dbContact.Id;
			ContentData.CurrentOrder.FK_DeliveryMode = -1;

			ContentData.CurrentOrder.DeliveryAddresses = _dataContext.Contact__AdressType__ContactAddress_Rep.Query(x => x.FK_Contact == dbContact.Id && x.AddressType.isDelivery == true).Select(x => new SelectListItem() { Value = x.ContactAddress.Id.ToString(), Text = x.ContactAddress.Address_1 + " ... ", Selected = false }).ToList();
			ContentData.CurrentOrder.DeliveryAddresses.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = true });

			ContentData.CurrentOrder.InvoicingAddresses = _dataContext.Contact__AdressType__ContactAddress_Rep.Query(x => x.FK_Contact == dbContact.Id && x.AddressType.isBilling == true).Select(x => new SelectListItem() { Value = x.ContactAddress.Id.ToString(), Text = x.ContactAddress.Address_1 + " ... ", Selected = false }).ToList();
			ContentData.CurrentOrder.InvoicingAddresses.Insert(0, new SelectListItem() { Value = "-1", Text = string.Empty, Selected = true });

			ContentData.CurrentOrder.NewRow = EmptyNewRow(ContentData.CurrentOrder.Id);

			ContentData.CurrentOrder.Details = new List<Models.MetaModels.OrderManagement.OrderDetail_MetaModel>();
		}

		private OrderDetail_MetaModel EmptyNewRow(int orderId)
		{
			OrderDetail_MetaModel toReturn = new OrderDetail_MetaModel();
			toReturn.RowMode = OrderDetail_MetaModel.enOrderDetailRowMode.Add;
			toReturn.Id = -99;
			toReturn.AllTaxeIncludedTotal = 0;
			toReturn.AppliedVATRate = 0;
			toReturn.FK_Order = orderId;
			toReturn.FK_Product = -1;
			toReturn.Quantity = 0;
			toReturn.TotalPrice = 0;
			toReturn.UnitPrice = 0;
			toReturn.VatTotal = 0;
			return toReturn;
		}
	}
}


///// <summary>
///// Update a row, it can be the NewRow id=0, a added row (id lesser than 0) or an existing row id greater than 0
///// </summary>
///// <param name="rowId"></param>
///// <param name="model"></param>
///// <returns></returns>
//[HttpPost, Authorize, CacheManager(enCacheMode.NoCache)] //Manage your cache; I Removed , Authorize to let google to index page
//public JsonResult UpdateRow(int rowId, AdvancedSamples_OrderWithDetailsModel model)
//{
//    string eMethod = eMethodBase + "UpdateRow[POST]";
//    object eParameters = new { model = "model" };
//    JsonResult toReturn = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
//    using (DataRepositories _dataContext = new DataRepositories())
//    {
//        if (rowId == -99)
//        {
//            model.CurrentOrder.NewRow = PrepareRow(_dataContext, model.CurrentOrder.Id, model.CurrentOrder.NewRow);
//        }
//        else
//        {
//            List<OrderDetail_MetaModel> newDetails = new List<OrderDetail_MetaModel>();
//            OrderDetail_MetaModel detailToAdd;
//            foreach (OrderDetail_MetaModel currentDetail in model.CurrentOrder.Details)
//            {
//                if (currentDetail.Id != rowId)
//                {
//                    detailToAdd = PrepareRow(_dataContext, model.CurrentOrder.Id, currentDetail);
//                }
//                else
//                {
//                    detailToAdd = currentDetail;
//                }
//                newDetails.Add(detailToAdd);
//            }
//            model.CurrentOrder.NewRow = EmptyNewRow(model.CurrentOrder.Id);
//            model.CurrentOrder.Details = newDetails;
//        }
//    }
//    string htmlContent = base.RenderPartialViewToString("_AdvancedSamples_OrderWithDetails_DetailRefresh", model);
//    toReturn.Data = new { @success = true, @htmlContent = htmlContent, @scriptToExecute = "$.fn.RebindButtons();" };
//    return toReturn;
//}

//private OrderDetail_MetaModel PrepareRow(DataRepositories _dataContext, int orderId, OrderDetail_MetaModel orderDetail)
//{
//    OrderDetail_MetaModel toReturn;
//    Product dbProduct = _dataContext.Product_Rep.Query(x => x.Id == orderDetail.FK_Product).FirstOrDefault();
//    if (dbProduct != null)
//    {
//        double vat = dbProduct.VAT.Value;
//        double totalPrice = double.Parse(dbProduct.UnitPrice.ToString()) * orderDetail.Quantity;
//        double allTaxeIncludedTotal = totalPrice * (1 + vat / 100);
//        double vatTotal = allTaxeIncludedTotal - totalPrice;
//        toReturn = new OrderDetail_MetaModel()
//        {
//            Id = orderDetail.Id,
//            FK_Order = orderId,
//            FK_Product = orderDetail.FK_Product,
//            Quantity = orderDetail.Quantity,
//            AppliedVATRate = decimal.Parse(vat.ToString()),
//            TotalPrice = decimal.Parse(totalPrice.ToString()),
//            VatTotal = decimal.Parse(vatTotal.ToString()),
//            AllTaxeIncludedTotal = decimal.Parse(allTaxeIncludedTotal.ToString())
//        };
//    }
//    else
//    {
//        toReturn = new OrderDetail_MetaModel()
//        {
//            Id = orderDetail.Id,
//            FK_Order = orderId,
//            FK_Product = orderDetail.FK_Product,
//            Quantity = orderDetail.Quantity,
//            AppliedVATRate = 0,
//            TotalPrice = 0,
//            VatTotal = 0,
//            AllTaxeIncludedTotal = 0
//        };
//    }
//    return toReturn;
//}